﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.Samples.IHandlers;
using Microsoft.VisualStudio.IntelliTrace;
using System.Diagnostics;
using System.Collections.Specialized;
using System.Globalization;

namespace Microsoft.VisualStudio.Samples.ConsoleWriters
{
    public class CheckpointChainConsoleWriter : ChainConsoleWriter, CheckpointChainHandler
    {
        public void ThreadCheckpointEvent(IntelliTraceEvent ev)
        {
            ThreadCheckpointEvent checkpointEvent = ev as ThreadCheckpointEvent;
            Debug.Assert(checkpointEvent != null);

            NameValueCollection eventProperties = new NameValueCollection();
            eventProperties.Add("Ordinal", checkpointEvent.Ordinal.ToString(CultureInfo.CurrentCulture));
            eventProperties.Add("Thread id", checkpointEvent.IntelliTraceThreadId.ToString(CultureInfo.CurrentCulture));
            eventProperties.Add("Event time", GetDateTimeFromEventTime(this.Process, checkpointEvent.EventTime).ToString("HH:mm:ss.fffffff", CultureInfo.CurrentCulture));
            // Get the event this checkpoint event points to and dump out its ordinal.
            IntelliTraceThread thread = null;
            foreach (IntelliTraceThread t in this.Process.Threads)
            {
                if (t.IntelliTraceThreadId == checkpointEvent.IntelliTraceThreadId)
                {
                    thread = t;
                    break;
                }
            }
            if (thread != null)
            {
                ThreadStreamChain threadEventChain = thread.CreateThreadChain<ThreadStreamChain>();
                OrdinalEvent e = threadEventChain.GetEvent(checkpointEvent.EventToken) as OrdinalEvent;
                Debug.Assert(e != null);
                eventProperties.Add("Thread event ordinal", e.Ordinal.ToString(CultureInfo.CurrentCulture));
            }

            DumpProperties(eventProperties);

            DumpStack(this.Process, checkpointEvent.StackFrames);
        }

        public void DiagnosticCheckpointEvent(IntelliTraceEvent ev)
        {
            DiagnosticCheckpointEvent notifyPointCheckpointEvent = ev as DiagnosticCheckpointEvent;
            Debug.Assert(notifyPointCheckpointEvent != null);

            NameValueCollection eventProperties = new NameValueCollection();
            eventProperties.Add("Ordinal", notifyPointCheckpointEvent.Ordinal.ToString(CultureInfo.CurrentCulture));
            eventProperties.Add("Event time", GetDateTimeFromEventTime(this.Process, notifyPointCheckpointEvent.EventTime).ToString("HH:mm:ss.fffffff", CultureInfo.CurrentCulture));
            DiagnosticStreamChain diagnosticEventChain = this.Process.CreateProcessChain<DiagnosticStreamChain>();
            OrdinalEvent e = diagnosticEventChain.GetEvent(notifyPointCheckpointEvent.EventToken) as OrdinalEvent;
            Debug.Assert(e != null);
            eventProperties.Add("Diagnostic event ordinal", e.Ordinal.ToString(CultureInfo.CurrentCulture));

            DumpProperties(eventProperties);
        }
    }
}
